package com.alinesno.cloud.common.web.base.form;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alinesno.cloud.common.core.orm.id.SnowflakeIdWorker;

/**
 * 表单提交拦截器
 * @author LuoAnDong
 * @since 2019年2月8日 上午10:43:38
 */
@Aspect
@Component
public class FormTokenInterceptor {

    private static final Logger log = LoggerFactory.getLogger(FormTokenInterceptor.class);
    private static final String FORM_TOKEN = "formToken" ; 

    /**
     * 创建token
     * @param joinPoint
     * @param token
     */
    @SuppressWarnings("unused")
	@Before("within(@org.springframework.stereotype.Controller *) && @annotation(token)")
    public void buildToken(final JoinPoint joinPoint, FormToken token){
    	log.debug("token = {}" , token);
        try {
            if (token != null) {
            	
                //获取 joinPoint 的全部参数
                Object[] args = joinPoint.getArgs();
                HttpServletRequest request = null;
                HttpServletResponse response = null;
                
                for (int i = 0; i < args.length; i++) {
                    //获得参数中的 request && response
                    if (args[i] instanceof HttpServletRequest) {
                        request = (HttpServletRequest) args[i];
                    }
                    if (args[i] instanceof HttpServletResponse) {
                        response = (HttpServletResponse) args[i];
                    }
                }

                boolean needSaveSession = token.save();
                if (needSaveSession){
                    String uuid = SnowflakeIdWorker.getIdStr() ;
                    log.debug("request = {}" , request);
                    request.getSession().setAttribute(FORM_TOKEN, uuid);
                    log.debug("进入表单页面，Token值为："+uuid);
                }

                boolean needRemoveSession = token.remove();
                if (needRemoveSession) {
                    if (isRepeatSubmit(request)) {
                        log.error("表单重复提交");
                        throw new FormRepeatException("表单重复提交");
                    }
                    request.getSession(false).removeAttribute(FORM_TOKEN);
                }
            }

        } catch (FormRepeatException e){
            throw e;
        } catch (Exception e){
        	e.printStackTrace(); 
        	log.error("FORM_TOKEN 发生异常 : "+e);
        }
    }

    /**
     * 判断是否重复提交 
     * @param request
     * @return
     * @throws FormRepeatException
     */
    private boolean isRepeatSubmit(HttpServletRequest request) throws FormRepeatException {
        Object serverTokenObj = request.getSession(false).getAttribute(FORM_TOKEN);
        
        if (serverTokenObj == null ) {
            return true;
        }
        
        System.out.println("formToken = " + request.getParameter("formToken"));
        
        Enumeration<String> enu=request.getParameterNames();  
        while(enu.hasMoreElements()){  
			String paraName=(String)enu.nextElement();  
			System.out.println(paraName+": "+request.getParameter(paraName));  
        }

        
        String clinetToken = request.getParameter(FORM_TOKEN) ;
        if (clinetToken == null || clinetToken.equals("")) {
            return true;
        }
        
        if (!serverTokenObj.equals(clinetToken)) {
            return true ;
        }
        
        log.debug("校验是否重复提交：表单页面 FORM_TOKEN 值为："+clinetToken + ",Session中的 FORM_TOKEN 值为:"+serverTokenObj);
        return false ;
    }
}
